
#include <atomic>
#include <thread>
#include <functional>
#include "html.h"

#ifndef AUTOCFGSSID
#define AUTOCFGSSID "ESP_WIFI"
#endif
#ifndef AUTOCFGPSW
#define AUTOCFGPSW "12345678"
#endif

#ifdef USE_8266
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
using TagWebSERVER = ESP8266WebServer;
#else
#include <WiFi.h>
#include <WebServer.h>
using TagWebSERVER = WebServer;
#endif

using FunWebServerCallback = std::function<bool(const char *)>;

class CWebControl
{

protected:

    void HandleHtmlRoot()
    {
        m_ControlWebServer.send(200, "text/html", AutoConfigHTML);
    }

    void HandleHtmlContrl()
    {
        if (m_WebServerCallback)
        {
            bool bRet = m_WebServerCallback(m_ControlWebServer.arg("btn_name").c_str());
            m_ControlWebServer.send(bRet ? 200 : 500, "text/html", m_ControlWebServer.arg("btn_name").c_str());
        }
    }

public:
    CWebControl() : m_bRun(false)
    {
    }

    ~CWebControl()
    {
        Stop();
    }

    void Init()
    {
        WiFi.mode(WIFI_AP_STA); // 双模式
        WiFi.setAutoReconnect(true);

        IPAddress ip, gateway, subnet;
        ip.fromString("192.168.2.1");
        gateway.fromString("192.168.2.1");
        subnet.fromString("255.255.255.0");
        WiFi.softAPConfig(ip, gateway, subnet);

        WiFi.softAP(AUTOCFGSSID, AUTOCFGPSW);

        m_ControlWebServer.on("/", std::bind(&CWebControl::HandleHtmlRoot, this));
        m_ControlWebServer.on("/Ctrl", HTTP_GET, std::bind(&CWebControl::HandleHtmlContrl, this));
    }

    void SetCallBack(FunWebServerCallback callback)
    {
        m_WebServerCallback = callback;
    }

#ifdef USE_8266

    void Stop()
    {
    }

#else

    void Stop()
    {
        m_bRun = false;
        m_ControlWebServer.close();
        if (m_LoopThread.joinable())
        {
            m_LoopThread.join();
        }
    }

#endif

#ifdef USE_8266

    void Run()
    {
        m_ControlWebServer.handleClient();
    }

#else

    void Run()
    {
        Stop();
        m_bRun = true;
        m_ControlWebServer.begin(80);
        m_LoopThread = std::thread(std::bind([&]
                                             {
            while (m_bRun)
        {
            m_ControlWebServer.handleClient();
        } }));
    }

#endif

private:
#ifndef USE_8266
    std::thread m_LoopThread;
#endif
    TagWebSERVER m_ControlWebServer;
    std::atomic_bool m_bRun;
    FunWebServerCallback m_WebServerCallback;
};